package 力扣;

/**
     给定一个链表，旋转链表，将链表每个节点向右移动 k 个位置，其中 k 是非负数。
     示例 1:
     输入: 1->2->3->4->5->NULL, k = 2
     输出: 4->5->1->2->3->NULL
     解释:
     向右旋转 1 步: 5->1->2->3->4->NULL
     向右旋转 2 步: 4->5->1->2->3->NULL
     示例 2:
     输入: 0->1->2->NULL, k = 4
     输出: 2->0->1->NULL
     解释:
     向右旋转 1 步: 2->0->1->NULL
     向右旋转 2 步: 1->2->0->NULL
     向右旋转 3 步: 0->1->2->NULL
     向右旋转 4 步: 2->0->1->NULL
 */
public class _61旋转链表 {

     public class ListNode {
     int val;
      ListNode next;
      ListNode(int x) { val = x; }
     }

   // 先遍历求得链表总长度count，同时将链表首尾相连；
    //再找到原链表的倒数第k+1个节点，该节点的next就是新链表的头结点。
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null || head.next == null || k == 0) return head;

        int count = 1; // 用来统计链表总结点数
        ListNode tmp = head;
        while (tmp.next != null) {
            count++;
            tmp = tmp.next;
        }
        k %= count;
        // 当k为0时，不需要旋转，
        if (k == 0) return head;

        // 不满足上述条件，必将进行旋转，所以先将首尾相连
        tmp.next = head;
        // 现在只需要找到倒数第k+1个节点
        for (int i = 0; i < count - k; i++) {
            tmp = tmp.next;
        }
        ListNode newHead = tmp.next;
        tmp.next = null;
        return newHead;
    }


    public ListNode rotateRight2(ListNode head, int k) {

         if( head == null || k == 0){
             return head;
         }
         int length = 1;
         ListNode curNode = head;
         while( curNode.next != null ){
             length++;
             curNode = curNode.next;
         }
         int loop = length - (k%length);
         ListNode tail  = curNode;
         curNode.next = head; //构成循环链表

        curNode = head;
        for (int i = 0; i < loop; i++) {
            curNode = curNode.next;
            tail = tail.next;
        }
        tail.next = null;
         return curNode;
    }
}
